package cn.devzyh.oms.coms.shipment.service;

import cn.devzyh.oms.common.core.util.R;
import cn.devzyh.oms.coms.api.order.constant.OrderConstants;
import cn.devzyh.oms.coms.api.order.dto.OrderDTO;
import cn.devzyh.oms.coms.api.order.entity.OrderDetail;
import cn.devzyh.oms.coms.api.order.entity.OrderHeader;
import cn.devzyh.oms.coms.api.shipment.converter.ShipmentConverter;
import cn.devzyh.oms.coms.api.shipment.dto.ShipmentDTO;
import cn.devzyh.oms.coms.api.shipment.entity.ShipmentDetail;
import cn.devzyh.oms.coms.api.shipment.entity.ShipmentHeader;
import cn.devzyh.oms.coms.flow.context.FlowContext;
import cn.devzyh.oms.coms.flow.executor.FlowNode;
import cn.devzyh.oms.coms.order.service.OrderHeaderService;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;

/**
 * 构建出库单工作流节点
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BuildShipmentNode implements FlowNode {

	private final OrderHeaderService orderHeaderService;

	private final ShipmentService shipmentService;

	@Override
	public R process(FlowContext ctx) {
		OrderDTO order = (OrderDTO) ctx.getMainCache();
		OrderHeader header = order.getHeader();

		ShipmentHeader shipmentHeader = ShipmentConverter.INSTANCE.toShipmentHeader(header);
		shipmentHeader.setId(null);
		List<ShipmentDetail> shipmentDetailList = new LinkedList<>();
		for (OrderDetail detail : order.getDetails()) {
			ShipmentDetail shipmentDetail = ShipmentConverter.INSTANCE.toShipmentDetail(detail);
			shipmentDetail.setId(null);
			shipmentDetail.setShipmentQuantity(0);

			shipmentDetailList.add(shipmentDetail);
		}

		ShipmentDTO dto = new ShipmentDTO();
		dto.setHeader(shipmentHeader);
		dto.setDetails(shipmentDetailList);

		R res = shipmentService.save(dto);
		if (res.failure()) {
			return res;
		}

		// 更新出库单号和状态
		header.setShipmentId(shipmentHeader.getId());
		LambdaUpdateWrapper<OrderHeader> wrapper = Wrappers.lambdaUpdate();
		wrapper.set(OrderHeader::getShipmentId, shipmentHeader.getId());
		wrapper.set(OrderHeader::getStatus, OrderConstants.Status.SHIPMENT);
		wrapper.eq(OrderHeader::getId, header.getId());
		orderHeaderService.update(wrapper);

		return R.ok();
	}

	@Override
	public R rollback(FlowContext ctx) {
		OrderDTO order = (OrderDTO) ctx.getMainCache();
		shipmentService.remove(order.getHeader().getShipmentId());

		LambdaUpdateWrapper<OrderHeader> wrapper = Wrappers.lambdaUpdate();
		wrapper.set(OrderHeader::getStatus, OrderConstants.Status.INIT);
		wrapper.eq(OrderHeader::getId, order.getHeader().getId());
		orderHeaderService.update(wrapper);

		return R.ok();
	}

}
